home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 6
/
QRZ Ham Radio Callsign Database - Volume 6.iso
/
mac
/
files
/
amiga
/
csrc720j.lzh
/
dir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-04
|
11KB
|
466 lines
/* dir.c */
#include <libraries/dos.h>
#include <exec/memory.h>
#include "mb.h"
/*
* Directory access routines.
*/
/*
* A directory item looks like this:
struct FileInfoBlock {
LONG fib_DiskKey;
LONG fib_DirEntryType;
char fib_FileName[108];
LONG fib_Protection;
LONG fib_EntryType;
LONG fib_Size;
LONG fib_NumBlocks;
struct DateStamp fib_Date;
char fib_Comment[80];
char padding[36];
};
*/
typedef struct FileInfoBlock FCB;
extern char tmpstr[];
extern short debug;
static int olddta;
static FCB *fcb = 0;
static struct InfoData *ID = 0L;
char wcstring[100];
/*
* Open directory, return first item.
*/
diropen(cp, p, dirdef)
UBYTE *cp;
DIRDEF *dirdef;
DIRENT *p;
{
long result;
if(fcb == 0) {
fcb = (FCB *)AllocMem((long)sizeof(*fcb),
(long)MEMF_PUBLIC|MEMF_CLEAR);
}
if(ID == 0) {
ID = (struct InfoData *)AllocMem((long)sizeof(*ID),
(long)MEMF_PUBLIC|MEMF_CLEAR);
}
/*
* Get the first directory entry.
*/
dirdef->lock = Lock(cp,ACCESS_READ);
if(dirdef->lock == 0L) {
p->size = -1;
return (false);
}
if(Info(dirdef->lock,ID) == 0L) {
/* If Info fails then the named file/device is NOT a disk */
dirdef->size = 0L;
dirdef->free = 0L;
return(false);
}
else {
dirdef->size =
((ID->id_BytesPerBlock*ID->id_NumBlocksUsed + 1023L) / 1024L);
dirdef->free =
((ID->id_BytesPerBlock * ID->id_NumBlocks + 1023L) / 1024L)
- dirdef->size;
}
/* Examine this name to find out what it is - it MUST be a directory */
if((result = Examine(dirdef->lock,fcb)) == 0L) {
UnLock(dirdef->lock);
p->size = -1;
return (false);
}
if(fcb->fib_DirEntryType < 0) { /* It's a file! That's WRONG! */
UnLock(dirdef->lock);
p->size = -1;
return (false);
}
if(dirnext(p,dirdef))return(false);
if(dodir(p)) return (true);
return (false);
}
freefcb()
{
if(fcb)FreeMem(fcb,(long)sizeof(*fcb));
if(ID)FreeMem(ID,(long)sizeof(*ID));
}
/*
* Return first and succeeding filenames in the directory.
* And if a wildcard is specified only return the matching
* names.
*/
dirnext(p, dirdef)
DIRENT *p;
DIRDEF *dirdef;
{
/* search for next filename in the directory */
while(true) {
if(ExNext(dirdef->lock,fcb) == 0L) {
p->size = -1;
UnLock(dirdef->lock);
return(1);
}
if (dodir(p)) {
return(0);
}
}
}
dodir(p)
DIRENT *p;
{
/* wcmatch checks wcstring against fcb->fib_FileName
If the wildcard is null then everything matches it and
wcmatch returns a true, otherwise it returns true only
if the wcstring and filename match
*/
if(wcmatch(&fcb->fib_FileName[0],&wcstring[0]) == 0)return(false);
strcpy(p->name,&fcb->fib_FileName[0]);
if(fcb->fib_DirEntryType >= 0) { /*It's a directory */
if(!match(p->name, "/")) {
return (false);
}
if(port->mode & (local | sysop)) {
strcat(p->name, "/");
}
else {
return (false);
}
}
/* return the size in Kb rounded up */
p->size = (fcb->fib_Size+01777)>>10;
return (true);
}
/*
* Modified form of getdir from original mbfile.c
* The amiga searches directories for wildcards in
* a different way than does the IBM. SO set it up
* for a wildcard match for the amiga.
*
*/
extern DIRPATH *dphd;
DIRPATH *setdir(p)
char *p;
{
register DIRPATH *dp;
register char *cp,*pp;
cp = p;
pp = &wcstring[0];
*pp = 0;
for(dp = dphd; dp isnt NULL; dp = dp->next)
if (dp->id is port->opt2) {
strcpy(port->line, dp->path);
while(*cp)*pp++ = *cp++;
*pp = 0;
return dp;
}
port->msg = mndir;
return NULL;
}
/* Check filename in *a against a possibly null wildcard string in *b */
wcmatch(a,b)
char *a,*b;
{
register char *p,*q;
p = a;
q = b;
/* If the wildcard is null then everything matches */
if(*q == 0)return(1);
if(*q == '*') {
/* Leading wildcard * in the pattern */
while(*p)p++;
while(*q)q++;
p--;
q--;
while(*q != '*') {
if(toupper(*p) == toupper(*q)) {
p--;
q--;
continue;
}
break;
}
if(*q == '*')return(1);
return(0);
}
while(*p && *q && (*q != '*')) {
if(toupper(*p) == toupper(*q)) {
p++;
q++;
continue;
}
break;
}
if((*p == 0) && (*q == 0))return(1);
if(*q == '*')return(1);
return(0);
}
/* Check call or @bbs in *a against a wildcard string in *b
Both are ln_call characters long and have trailing spaces added
*/
wmatch(a,b)
char *a,*b;
{
register char *p,*q;
register short i;
char inname[ln_call+1],wildc[ln_call+1];
/* copy the two input strings into temporary storage, removing the
trailing blanks. This routine is obviously a slightly modified
form of the directory wcmatch routine.
The copy also forces both strings to upper case to save having
to do it later.
*/
p = a;
q = inname;
for(i = 0;i<ln_call;i++) {
if(*p == ' ')break;
*q++ = toupper(*p++);
}
*q++ = 0;
p = b;
q = wildc;
for(i = 0;i<ln_call;i++) {
if(*p == ' ')break;
*q++ = toupper(*p++);
}
*q++ = 0;
p = inname;
q = wildc;
/* If the wildcard is null then everything matches */
if(*q == 0)return(1);
if(*q == '*') {
/* Leading wildcard * in the pattern */
while(*p)p++;
while(*q)q++;
p--;
q--;
while(*q != '*') {
if(*p == *q) {
p--;
q--;
continue;
}
break;
}
if(*q == '*')return(1);
return(0);
}
while(*p && *q && (*q != '*')) {
if(*p == *q) {
p++;
q++;
continue;
}
break;
}
if((*p == 0) && (*q == 0))return(1);
if(*q == '*')return(1);
return(0);
}
/* Check title in *a against a quoted string in *b */
/* If the string occurs anywhere in the title then
return non-null.
*/
umatch(a,b)
char *a,*b;
{
register char *p,*q,*r,*s;
short i,j;
if((i = strlen(a)) > 79) {
i = 79;
*(a+79) = 0;
}
if((j = strlen(b)) > 79) {
j = 79;
*(b+79) = 0;
}
j -= 2; /* Don't count the quotes */
if(j > i)return(0); /* Quoted string is longer than title */
r = a + i - j;
for(p = a;p <= r;p++) {
q = p;
s = b+1; /* Skip the quote */
while(*s && (*s != '"')) {
if(toupper(*q) != *s)break; /* The string is already upper */
q++;
s++;
}
if((*s == '"') || (*s == 0))return(1);
}
return(0);
}
kill_list()
{
register int from,to,i;
register PORTS *p;
p = port;
ioport(cport);
if(!num(port->fld[1]) || !num(port->fld[2])) {
port->msg = mwhat;
ioport(p);
return;
}
from = atoi(port->fld[1]);
to = atoi(port->fld[2]);
if((from < 1) || (to < 1) || (from >= to)) {
port->msg = mwhat;
ioport(p);
return;
}
sprintf(tmpstr,"Delete messages from #%d to #%d\n",from,to);
outstr(tmpstr);
if(sure())return;
/* Search forwards through the file to find the first message number
The messages are more likely to be near the front of the file than
the end. The end of the file has more recent messages.
However, a binary search would be the best strategy and I'll put it in
here when I have time.
*/
check_mail();
unlock_mail();
for(i = 1; i <= mfhs->last ; i++) {
read_rec(mfl, i, (char *)port->mmhs);
/*
sprintf(tmpstr,"rec#%d = msg#%d\n",i,port->mmhs->number);
ttputs(tmpstr);
*/
if (port->mmhs->number >= from) break;
}
if((port->mmhs->number < from) || (port->mmhs->number > to)) {
outstr("No messages in the specified range\n");
return;
}
/* This re-reads the very first record but the loop is easier to
write this way.
Delete messages within the specified range.
*/
for( ; i <= mfhs->last ; i++) {
read_rec(mfl, i, (char *)port->mmhs);
if (port->mmhs->number > to) break;
/* Is it already dead? */
if(port->mmhs->stat & m_kill) continue;
/* Don't kill traffic this way. They must be done individually */
if(port->mmhs->type is 'T')continue;
sprintf(tmpstr,"%d",port->mmhs->number);
outstr(tmpstr);
outstr(" - Killed\n");
port->mmhs->stat setbit m_kill;
write_rec(mfl, i, (char *)port->mmhs);
makehdr2();
}
sprintf(tmpstr,"from %d to %d",from,to);
log('M', 'K', 'L', tmpstr);
ioport(p);
port->msg = mdone;
titles();
}
char reject[TOT_REJECT][3][ln_call];
short num_reject = 0;
get_reject()
{
/* This routine MUST be called before the window is opened */
FILE *fp;
register char *p,*q;
register int fc,i;
if((fp = fopen("reject.btn","r")) == NULL)return;
while(fgets(&tmpstr[0],80,fp) != NULL) {
p = tmpstr;
if(*p == '\n')continue;
fc = 0;
while(1) {
switch(*p) {
case '<': /* FROM field */
p++;
fc++;
q = &reject[num_reject][2][0];
pcall(q,p);
break;
case '@': /* AT (BBS) field */
p++;
fc++;
q = &reject[num_reject][1][0];
pcall(q,p);
break;
case '>': /* TO field */
p++;
fc++;
q = &reject[num_reject][0][0];
pcall(q,p);
break;
}
while((*p != ' ') && (*p != '\n') && *p)p++;
if((*p == '\n') || (*p == 0))break;
while(*p == ' ')p++;
}
if(fc == 0) { /* No fields found .. don't use it */
reject[num_reject][0][0] = 0;
reject[num_reject][1][0] = 0;
reject[num_reject][2][0] = 0;
continue;
}
if(num_reject++ > TOT_REJECT-1)break;
}
fclose(fp);
if(num_reject > TOT_REJECT-1)num_reject = TOT_REJECT-1;
printf("\nReject.btn list\n");
/* This loop does not only prepare the reject list for printing.
It also converts the fields to upper case. So do not delete
the entire loop
*/
for(fc = 0;fc < num_reject;fc++) {
for(i=0;i<3;i++) {
p = tmpstr;
*p = 0;
q = &reject[fc][i][0];
while(*q && (*q != ' ') && (q < &reject[fc][i][ln_call])) {
*q = toupper(*q);
*p++ = *q++;
*p = 0;
}
printf("%c%s ",">@<"[i],&tmpstr[0]);
}
printf("\n");
}
printf("\n");
}
test_reject()
{
register short i;
/* Allow sysop to send them out, but reject them from anyone else? */
/* How about rejecting only when forwarding? */
if(port->mode == local)return(0);
for(i=0;i<num_reject;i++) {
if(reject[i][0][0]) {
if(!matchn(&reject[i][0][0],port->mmhs->to,ln_call))continue;
}
if(reject[i][1][0]) {
if(!matchn(&reject[i][1][0],port->mmhs->bbs,ln_call))continue;
}
if(reject[i][2][0]) {
if(!matchn(&reject[i][2][0],port->mmhs->from,ln_call))continue;
}
return(1);
}
return(0);
}